﻿
using Microsoft.EntityFrameworkCore;
using FreeRedis;
using Newtonsoft.Json;
using Microsoft.AspNetCore.Mvc;
using static System.Reflection.Metadata.BlobBuilder;
using Newtonsoft.Json.Linq;
using CQIE.LabAssist.Models;
using System;
using CQIE.LabAssist.PublicHelp;
namespace CQIE.LabAssist.DataAccesss
{

    public class UserService : IUserService
    {

        private readonly _DbContext _Db;
        private readonly JwtHelp _jwtHelper;
      
    
        public UserService(JwtHelp jwtHelper,_DbContext db)
        {
             _jwtHelper = jwtHelper;
            _Db = db;
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="num"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public JsonResult Login(string num, string password)
        {
            var user = _Db.Users.Where(w => w.num == num && w.Password == password && w.State == true).FirstOrDefault();
            var token = "0";
            var role = "0";
            var outcome = false;
            var userId = 0;
            var userName = "0";
            if (user != null)
            {
                userId = user.Id;
                userName = user.Name;
                outcome = true;
                role = _Db.Roles.Where(r => r.Id == _Db.UserRoles.Where(w => w.UserId == user.Id).Select(w => w.RoleId).FirstOrDefault()).Select(w => w.Name).FirstOrDefault();
                token = _jwtHelper.CreateToken(role);
            }
            else
            {
                outcome = false;

            }
            var Result = new
            {
                outcome = outcome,
                userId = userId,
                roleName=role,
                userName = userName,
                token = token
            };
            return new JsonResult(Result);
        }

        /// <summary>
        /// 通过角色获取对应菜单栏
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public  JsonResult getMenu(int userId)
        {
            // 首先，获取与用户ID关联的角色ID
            int roleId =  _Db.UserRoles
                .Where(ur => ur.UserId == userId)
                .Select(ur => ur.RoleId)
                .FirstOrDefault();

            // 然后，获取与角色ID关联的所有菜单项
            var userMenues = _Db.RoleMenues.Where(rm => rm.RoleId == roleId).Select(um => um.SysMenuId).ToList();

            // 然后，获取与角色ID关联的所有菜单项及其子菜单项
            var sysMenus =  _Db.Menus
                .Where(w => userMenues.Contains(w.Id)) // 顶级菜单或与角色ID关联的菜单
                .Select(w => new
                {
                    w.Id,
                    w.Name,
                    w.Url,
                    w.icon,
                    Children = w.Children.Select(c => new
                    {
                        c.Id,
                        c.Name,
                        c.Url
                    })
                })
                .ToList();

            return new JsonResult(sysMenus);
        }

        /// <summary>
        /// 注册实验室管理员
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public bool addUser(User user, List<string> roles)
        {
            if(_Db.Users.Any(u=>u.num == user.num))
            {
                return false;
            }
            User newUser = new User();
            newUser.num = user.num;
            newUser.State = true;
            newUser.Name = user.Name;
            newUser.acadminianId = user.acadminianId;
            newUser.Password = user.Password;
            newUser.Phone = user.Phone;
            Academician academician= _Db.Academicians.Where(ac=>ac.Id==user.acadminianId).FirstOrDefault(); 
            newUser.Academician = academician;
            _Db.Users.Add(newUser);

            for (int i = 0; i < roles.Count; i++)
            {
                
                UserRole userRole = new UserRole();
                userRole.User = newUser;
                userRole.UserId = newUser.Id;
                userRole.Role = _Db.Roles.Where(role => role.Name == roles[i].ToString()).FirstOrDefault();
                userRole.RoleId = userRole.Role.Id;
                _Db.UserRoles.Add(userRole);
            }
            if (_Db.SaveChanges() > 0)
                return true;
            else
                return false;
        }
        /// <summary>
        /// 获取用户
        /// </summary>
        /// <returns></returns>
        public JsonResult getUser()
        {
            var role=_Db.UserRoles.ToList();
            var users = _Db.Users.Include(w=>w.Academician).ToList().Select(w => new
            {
               id=w.Id,
               name=w.Name,
               number=w.num,
               password=w.Password,
               phone=w.Phone,
               state=w.State,
               academician=w.Academician.Name,
               academicianId=w.acadminianId,
               role=
                
                   _Db.UserRoles.Where(e=>e.UserId==w.Id).Select(ur => ur.Role.Name).ToList()
               
            }
            );
            return new JsonResult( users );
        }

        /// <summary>
        /// 修改用户
        /// </summary>
        /// <param name="user"></param>
        /// <param name="roles"></param>
        /// <returns></returns>
        public bool updateUser(User user, List<string> roles)
        {
            // Find the existing user in the database
            User existingUser = _Db.Users.Find(user.Id);
            if (existingUser == null)
            {
                // Handle the case where the user was not found
                return false;
            }

            // Update the user's information
            existingUser.num = user.num;
            existingUser.State = user.State;
            existingUser.Name = user.Name;
            existingUser.Password = user.Password;
            existingUser.Phone = user.Phone;

            // Find the academician for the user
            Academician academician = _Db.Academicians.Where(ac => ac.Id==user.acadminianId).FirstOrDefault();
            if (academician == null)
            {
                // Handle the case where the academician was not found
                return false;
            }
            existingUser.Academician = academician;
            existingUser.acadminianId = academician.Id;

            // Create a list to store the current user roles
            var currentUserRoles = new List<UserRole>();

            // Get the current user roles from the database
            currentUserRoles = _Db.UserRoles.Where(ur => ur.UserId == existingUser.Id).ToList();

            // Create a list to store the new user roles
            var newUserRoles = new List<UserRole>();

            // Assign the roles to the user
            foreach (var role in roles)
            {
                Role dbRole = _Db.Roles.Where(r => r.Name == role).FirstOrDefault();
                if (dbRole == null)
                {
                    // Handle the case where the role was not found
                    continue;
                }

                var userRole = new UserRole
                {
                    User = existingUser,
                    UserId = existingUser.Id,
                    Role = dbRole,
                    RoleId = dbRole.Id
                };
                newUserRoles.Add(userRole);
            }

            // Remove roles that are no longer in the new list
            foreach (var currentUserRole in currentUserRoles)
            {
                if (!newUserRoles.Any(ur => ur.RoleId == currentUserRole.RoleId))
                {
                    // Role is no longer in the new list, so remove it
                    _Db.UserRoles.Remove(currentUserRole);
                }
            }

            // Add new roles that were not in the old list
            foreach (var newUserRole in newUserRoles)
            {
                if (!currentUserRoles.Any(ur => ur.RoleId == newUserRole.RoleId))
                {
                    // Role is new, so add it
                    _Db.UserRoles.Add(newUserRole);
                }
            }

            // Save the changes to the database
            if (_Db.SaveChanges() > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="UserId"></param>
        /// <returns></returns>
        public bool deleteUser(int UserId)
        {
            var s=_Db.Users.Where(w=>w.Id == UserId).FirstOrDefault();
            _Db.Users.Remove(s);
            return _Db.SaveChanges()>0;
        }


        /// <summary>
        /// 所有数据
        /// </summary>
        /// <returns></returns>
        public JsonResult getRolesMenuStatistics()
        {
            var roleMenuCounts = _Db.RoleMenues
                .Include(w => w.SysMenu)
                .GroupBy(rm => rm.role.Id)
                .Select(g => new
                {
                    RoleId = g.Key,
                    RoleName = g.FirstOrDefault().role.Name,
                    MenuCount = g.Count(),
                    Menus = g.Select(rm => new
                    {
                        Menid = rm.SysMenu.Id,
                        MenuName = rm.SysMenu.Name,
                        ChildrenMenus = g.SelectMany(cm => cm.SysMenu.Children)
                            .Where(child => child.ParentId == rm.SysMenuId)
                            .Select(child => new
                            {
                                Menid = child.Id,
                                MenuName = child.Name
                            })
                    })
                })
                .ToList();

            return new JsonResult(roleMenuCounts);
        }

        /// <summary>
        /// 所有菜单
        /// </summary>
        /// <returns></returns>
        public JsonResult getAllMenu()
        {
            var sysMenus = _Db.Menus
               
               .Select(w => new
               {
                   w.Id,
                   w.Name,
                   w.Url,
                   w.icon,
                   Children = w.Children.Select(c => new
                   {
                       c.Id,
                       c.Name,
                       c.Url
                   })
               })
               .ToList();
            return new JsonResult(sysMenus);

        }

       /// <summary>
       /// 所有角色
       /// </summary>
       /// <returns></returns>
        public JsonResult getAllRoles()
        {
            var roles = _Db.Roles.ToList();
            return new JsonResult(roles);
        }
       
        /// <summary>
        /// 某角色权限
        /// </summary>
        /// <param name="roleId"></param>
        /// <returns></returns>
        public IActionResult getRolesMenuByid(int roleId)
        {

            var roleMenuCounts = _Db.RoleMenues
                .Include(w => w.SysMenu)
                .Where(rm => rm.role.Id == roleId)
                .GroupBy(rm => rm.role.Id)
                .Select(g => new
                {
                  
                    Menus = g.Select(rm => new
                    {
                        Menid = rm.SysMenu.Id,
                        MenuName = rm.SysMenu.Name,
                        ChildrenMenus = g.SelectMany(cm => cm.SysMenu.Children)
                            .Where(child => child.ParentId == rm.SysMenuId)
                            .Select(child => new
                            {
                                Menid = child.Id,
                                MenuName = child.Name
                            })
                    })
                })
                .ToList();

            return new JsonResult(roleMenuCounts);
        }

        public IActionResult getOneMenu()
        {

            var roleMenuCounts = _Db.Menus
                .Where(w=>w.ParentId==null) 
                .Select(g=>new
                {
                    Menid = g.Id,
                    MenuName = g.Name,
                })
                .ToList();

            return new JsonResult(roleMenuCounts);
        }

        public JsonResult getOneMenuByid(int roleId)
        {
            var res=_Db.RoleMenues.Where(w=>w.RoleId==roleId).Include(W=>W.SysMenu)
                 .Select(g => new
                 {

       
                         Menid = g.SysMenu.Id,
                         MenuName = g.SysMenu.Name,
                        
                     
                 })
                .ToList();
            return new JsonResult(res);
        }
        public bool jusSetting(int roleid, int menid, bool state)
        {
            if(state)
            {
                var r=_Db.Roles.Where(w=>w.Id==roleid).FirstOrDefault();
                var m=_Db.Menus.Where(w=>w.Id == menid).FirstOrDefault();
                var rm = new RoleMenue();
                rm.role = r;
                rm.SysMenu = m;
                rm.SysMenuId = menid;
                rm.RoleId = roleid;
                _Db.RoleMenues.Add(rm);
                return _Db.SaveChanges()>0;
            }
            else
            {
                  var rm= _Db.RoleMenues.Where(w => w.SysMenuId == menid && w.RoleId == roleid).FirstOrDefault();
                _Db.Remove(rm);
                return _Db.SaveChanges()>0;
            }
           
           
        }
        public bool roleSetting(int roleid, string name)
        {
            var r=_Db.Roles.Where(w=>w.Id==roleid).FirstOrDefault();
            r.Name= name;
            _Db.Update(r);
            return _Db.SaveChanges()>0;
        }

        public JsonResult menuTwo(int menid)
        {
            var res=_Db.Menus.Where(w=>w.ParentId==menid).ToList();
            return new JsonResult(res);
        }
        public JsonResult getUserInfo(int uid)
        {

            User user = _Db.Users.Include(u=>u.Academician).Where(w=>w.Id==uid).FirstOrDefault(); 
            return new JsonResult(user);
        }
        public bool changeUserInfo(User nuser)
        {

            User user = _Db.Users.Include(u => u.Academician).Where(w => w.Id == nuser.Id).FirstOrDefault();
            user.Name= nuser.Name;
            user.Phone= nuser.Phone;

            return _Db.SaveChanges() > 0;
        }
        public bool changeUserPassword(User nuser)
        {

            User user = _Db.Users.Include(u => u.Academician).Where(w => w.Id == nuser.Id).FirstOrDefault();
            user.Password= nuser.Password;

            return _Db.SaveChanges() > 0;
        }

    }


}
